package com.beone.admin.controller;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.base.common.util.DateUtil;
import com.beone.admin.entity.ImportDetail;
import com.beone.admin.entity.TaskTemplateDetail;
import com.beone.admin.service.ImportDetailService;
import com.beone.admin.service.TaskTemplateDetailService;
import com.beone.admin.vo.TaskScheduleVO;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import com.base.SuperController;
import com.base.common.beans.Result;
import com.beone.admin.annotation.Log;
import com.beone.admin.common.AdminConstants;
import com.beone.admin.entity.BaseUser;
import com.beone.admin.entity.TaskTemplate;
import com.beone.admin.exception.MvcException;
import com.beone.admin.service.ImportLogService;
import com.beone.admin.service.TaskTemplateService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

/**
 * @Title 排班模板 前端控制器
 * @Author 秦波
 * @Version 1.0 on 2019-06-01
 * @Copyright 贝旺科权
 */
@Controller
@RequestMapping("/admin/taskTemplate")
@Api(value = "排班模板管理模块", tags = {"排班模板管理接口"})
public class TaskTemplateController extends SuperController {

    private static final Logger log = LoggerFactory.getLogger(TaskTemplateController.class);

    @Autowired
    private TaskTemplateService taskTemplateService;
    @Autowired
    private ImportLogService importLogService;
    @Autowired
    private TaskTemplateDetailService taskTemplateDetailService;
    @Autowired
    private ImportDetailService importDetailService;

    /**
     * 排班模板管理 入口 --> index
     * 
     * @return
     */
    @GetMapping("")
    public String index() throws MvcException {
        return "taskTemplate/index";
    }

    /**
     * 排班模板管理 显示添加页面
     * 
     * @return
     */
    @GetMapping("/showAdd")
    public String showAdd() throws MvcException {
        return "taskTemplate/form";
    }

    /**
     * 排班模板管理 显示修改页面
     * 
     * @return
     */
    @GetMapping("/showUpdate/{id}")
    public String showUpdate(@PathVariable("id") String id, ModelMap model) throws MvcException {
        try {
            model.addAttribute("id", id);
            model.addAttribute("entity", taskTemplateService.selectById(id));
        } catch (Exception e) {
            log.error("showUpdate 异常 e = {}", e);
            throw new MvcException(e.getMessage());
        }
        return "taskTemplate/form";
    }

    /**
     * 排班模板管理分页列表 JSON
     * 
     * @param entity
     * @param currPage
     * @param pageSize
     * @return
     */
    @ApiOperation(value = "排班模板列表", notes = "排班模板列表分页查询")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "page", value = "当前页码", required = true, paramType = "param", dataType = "int"),
        @ApiImplicitParam(name = "rows", value = "每页最大显示记录数", required = true, paramType = "param", dataType = "int")})
    @RequestMapping(value = "/list", produces = MediaType.APPLICATION_JSON_UTF8_VALUE,
        method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public Object showList(TaskTemplate entity,
        @RequestParam(value = "page", defaultValue = AdminConstants.DEFAULT_PAGE_NUM) int currPage,
        @RequestParam(value = "rows", defaultValue = AdminConstants.PAGE_SIZE) int pageSize) {
        return taskTemplateService.getTaskTemplatePagination(entity, currPage, pageSize);
    }

    /**
     * 保存排班模板
     * 
     * @param entity
     * @return
     */
    @ApiOperation(value = "保存排班模板", notes = "保存排班模板 主键属性为空新增,否则修改")
    @ApiImplicitParam(name = "entity", value = "{title}详细实体", required = true, paramType = "form", dataType = "object")
    @Log(desc = "排班模板", type = Log.LOG_TYPE.SAVE)
    @PostMapping(value = "/save", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public Object save(TaskTemplate entity) {
        if (taskTemplateService.insertOrUpdate(entity)) {
            return super.responseResult("success", "成功！");
        }
        return super.responseResult("fail", "失败！");
    }

    ;

    /**
     * 删除排班模板
     * 
     * @param id
     * @return
     */
    @ApiOperation(value = "删除排班模板", notes = "根据排班模板Id，删除排班模板")
    @ApiImplicitParam(name = "id", value = "实体ID", required = true, paramType = "param", dataType = "object")
    @Log(desc = "删除排班模板", type = Log.LOG_TYPE.DEL)
    @PostMapping(value = "/delete/{id}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public Object delete(@PathVariable("id") Integer id) {
        if (taskTemplateService.deleteById(id)) {
            return super.responseResult("success", "成功！");
        }
        return super.responseResult("fail", "失败！");
    }

    /**
     * 导出模板
     * @param response
     * @throws Exception
     */
    @GetMapping(value = "/exportTemplate")
    public void exportTemplate(HttpServletResponse response
                                 ,Integer deptId
                                 ,String month
    ) throws Exception {
        XSSFWorkbook wb = taskTemplateService.getExcelForTemplate(deptId, month);

        response.setHeader("content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        // 下载文件的默认名称
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("导入模板.xlsx", "UTF-8"));
        wb.write(response.getOutputStream());
    }

    /**
     * 导出数据
     * @param response
     * @throws Exception
     */
    @GetMapping(value = "/export")
    public void exportData(HttpServletResponse response
                                ,Integer deptId
                                ,Date startDate
                                ,Date endDate
    ) throws Exception {
        XSSFWorkbook wb = taskTemplateService.getExcelWithData(deptId, startDate, endDate);

        response.setHeader("content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        // 下载文件的默认名称
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("导出数据.xlsx", "UTF-8"));
        wb.write(response.getOutputStream());
    }

    /**
     * 导入数据
     * @param file
     * @param request
     * @return
     */
    @PostMapping(value = "/import")
    @ResponseBody
    public Result importData(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
        if (file == null) {
            return Result.failure("文件不能为空");
        }
        try {
            // FIXME 临时用空用户
            // importLogService.recordImportLog(ControllerUtils.getAdminUser(request), file.getInputStream());
            importLogService.recordImportLog(new BaseUser(), file.getInputStream());
            return Result.success("导入成功");
        } catch (IOException e) {
            return Result.failure("上传失败");
        }
    }

    /**
     * 获取表格数据
     * @param deptId
     * @param startDate
     * @param endDate
     * @return
     */
    @RequestMapping(value = "/getData", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Result getData(Integer deptId, Date startDate, Date endDate) {
        TaskTemplate template = taskTemplateService.getTaskTemplate(deptId);
        if (template != null) {
            List<TaskTemplateDetail> fieldList = taskTemplateDetailService.getDetailListByTemplatId(template.getId());
            List<ImportDetail> dataList = importDetailService.getImportDetailList(deptId, startDate, endDate);
            Map<Integer, List<ImportDetail>> dataMap = dataList.stream().collect(Collectors.groupingBy(ImportDetail::getTemplateDetailId));

            List<TaskScheduleVO> resultList = new ArrayList<>(fieldList.size());
            for (int i = 0; i < fieldList.size(); i++) {
                TaskTemplateDetail field =  fieldList.get(i);
                TaskScheduleVO schedule = new TaskScheduleVO(i+1, field.getFieldName(), field.getParentName());
                List<ImportDetail> thisDataList = dataMap.get(field.getId());
                buildData(schedule, thisDataList);
                resultList.add(schedule);
            }
            return Result.success("查询成功", resultList);
        }
        return Result.success("查询成功，没有数据", new TaskScheduleVO());
    }

    private void buildData(TaskScheduleVO schedule, List<ImportDetail> dataList) {
        if (dataList == null) {
            return;
        }
        dataList.forEach(data -> {
            int day = DateUtil.dayOfWeekDay(data.getDetailDate());
            switch (day) {
                case 0:
                    schedule.setSunday(data.getDetailValue());
                    break;
                case 1:
                    schedule.setMonday(data.getDetailValue());
                    break;
                case 2:
                    schedule.setTuesday(data.getDetailValue());
                    break;
                case 3:
                    schedule.setWednesday(data.getDetailValue());
                    break;
                case 4:
                    schedule.setThursday(data.getDetailValue());
                    break;
                case 5:
                    schedule.setFriday(data.getDetailValue());
                    break;
                case 6:
                    schedule.setSaturday(data.getDetailValue());
                    break;
            }
        });
    }
}
